package syntaxclass;

import java.util.LinkedList;
import java.util.List;

import polyglot.ast.ClassMember;
import polyglot.ast.FieldDecl;
import polyglot.ast.Node;
import polyglot.ast.NodeFactory;
import polyglot.ast.TypeNode;
import polyglot.types.Flags;
import polyglot.util.Position;
import polyglot.util.TypedList;
import xaj.ast.XAJNodeFactory;
import xaj.ast.XAJOps;
import abc.aspectj.ast.AspectBody;
import abc.aspectj.ast.AspectDecl;
import abc.aspectj.ast.AspectDecl_c;
import abc.aspectj.ast.IntertypeFieldDecl;

public class AJSynchro extends AspectDecl_c implements XAJOps, AspectDecl {
	
	private TypeNode nameClass;
	
	public AJSynchro(Position pos, TypeNode name, AspectBody body) {
		super(pos, false, Flags.NONE, "AJSynchro" + name.toString(),
				null, new TypedList(new LinkedList(), TypeNode.class, false),
				null, body);
		nameClass = name;
	}
	
	@Grammar extends aspect_declaration {
		AJSynchro ::= "synchronizer" t = type
		  "{" a = AJSynchroBody "}"
		    {
			  AspectBody body = new AspectBody_c(parser.pos(a), a);
			  RESULT = new AJSynchro(parser.pos(t), t, body);
			};
		AJSynchroBody ::= a = AJSynchroBody
		                      m = class_member_declaration {a.add(m); RESULT = a;};
		AJSynchroBody ::= a = AJSynchroBody
		                  m = AJSynchroMethod {a.add(m); RESULT = a;};
		AJSynchroBody ::=  {RESULT = new TypedList(new LinkedList(), ClassMember.class, false);};
	}
	
	public Node desugar(/*Context ct,*/ NodeFactory ft) {
		XAJNodeFactory nf = (XAJNodeFactory) ft;
		
		List members = new TypedList(new LinkedList(), ClassMember.class, false);
		List listbody = body().members();
		ClassMember c;
		for(int i = 0; i < listbody.size(); i++) {
			c = (ClassMember) listbody.get(i);
			if(c instanceof FieldDecl) {
				FieldDecl field = (FieldDecl) c;
				IntertypeFieldDecl inter = nf.IntertypeFieldDecl(c.position(), field.flags(),
						field.type(), nameClass, field.name(), field.init());
				members.add(field);
			} else
				members.add(c.copy());
		}
		AspectBody b = nf.AspectBody(body.position(), members);
		AspectDecl a = nf.AspectDecl(position(), false, flags, name(), superClass,
				interfaces, per, b);		
		return a;
	}
}